package com.wn.sddfp.trade.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wn.bank.access.api.TradeLogApi;
import com.wn.sddfp.common.model.dto.bank.BankCardRequestDto;
import com.wn.sddfp.common.model.dto.bank.BaseResult;
import com.wn.sddfp.common.model.dto.borrow.*;
import com.wn.sddfp.common.model.dto.user.UserInfoVo;
import com.wn.sddfp.common.model.result.Result;
import com.wn.sddfp.trade.entity.BorrowRecord;
import com.wn.sddfp.trade.mapper.BorrowRecordMapper;
import com.wn.sddfp.trade.service.IBorrowRecordService;
import com.wn.sddfp.trade.utils.TokenUtils;
import com.wn.system.api.UserApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * @author yellow Docter
 * @date 2023 -07-31
 * @desc    Primary可以理解为默认优先选择, 同时不可以同时设置多个,
 *          内部实质是设置BeanDefinition的primary属性
 */
@Slf4j
@Service
public class IBorrowRecordServiceImpl extends ServiceImpl<BorrowRecordMapper, BorrowRecord> implements IBorrowRecordService {

    @Autowired
    private UserApi userApi;

    /**
     * 添加借款的业务的流程
     * @param borrowRecordDTO
     */
    @Override
    public void addBorrowRecord(BorrowRecordDTO borrowRecordDTO) {

        //01 拿到 userId
        String userId = TokenUtils.getHeaderUserId();
        System.out.println("userId = " + userId);

        //02 远程调用 拿到userInfoVo
        Result<UserInfoVo> infoVoResult = userApi.findUserById(Long.valueOf(userId));
        UserInfoVo userInfoVo = infoVoResult.getData();
        System.out.println("userInfoVo = " + userInfoVo);

        //03 创建 BorrowRecord
        BorrowRecord borrowRecord = new BorrowRecord();

        //用户id
        borrowRecord.setUserId(Long.valueOf(userId));

        //借款描述
        borrowRecord.setDescription("无");
        borrowRecord.setType("TYPE");

        //借款天数
        borrowRecord.setPeriod(borrowRecordDTO.getPeriod());
        //借款金额
        borrowRecord.setAmount(borrowRecordDTO.getAmount());

        //机构收益
        borrowRecord.setInvestRate(new BigDecimal("3"));
        //借款人利率
        borrowRecord.setBorrowerRate(new BigDecimal("3"));
        //平台的利率
        borrowRecord.setCommissionRate(new BigDecimal("3"));

        //还款方式
        //  // "DEBX", "等额本息" /"DEBJ", "等额本金"  /"ALL", 一次性还款（含本息）  / "XXHB", "先息后本"
        borrowRecord.setRepaymentWay("DEBJ");

        //借款状态
        borrowRecord.setBorrowStatus("NEW");
        //时间
        borrowRecord.setCreateDate(new Date());
        borrowRecord.setModifyDate(new Date());
        //状态 false
        borrowRecord.setStatus(false);

        //随机一个请求码
        borrowRecord.setReqCode(UUID.randomUUID().toString().substring(0,12));

        borrowRecord.setUserCode(userInfoVo.getUserCode());
        //借款码
        borrowRecord.setBorrowRecordNo("BO_" + UUID.randomUUID().toString().substring(0,12));

        //设置 用户名
        borrowRecord.setName(covertName(userInfoVo));

        System.out.println("borrowRecord = " + borrowRecord);

        //04 存储数据
        save(borrowRecord);

    }

    @Override
    public Pages<BorrowRecordVo> queryBorrowRecord(Integer pageNum, Integer pageSize, BorrowRecordQuery borrowRecordQuery) {

        //分页查询
        //01 组装分页数据
        IPage<BorrowRecord> page = new Page<>();

        //02 条件查询
        LambdaQueryWrapper<BorrowRecord> borrowRecordLambdaQuery = Wrappers.lambdaQuery(BorrowRecord.class);

        //借款期限的范围查询
        borrowRecordLambdaQuery.between(
                !Objects.isNull(borrowRecordQuery.getStartPeriod()),
                BorrowRecord::getPeriod,
                borrowRecordQuery.getStartPeriod(),
                borrowRecordQuery.getEndPeriod());

        //条件是否是 and 或者or 需要问项目经理   这里为了方便演示 统一使用or
        borrowRecordLambdaQuery.or();

        //借款状态查询
        borrowRecordLambdaQuery.eq(
                !StringUtils.isEmpty(borrowRecordQuery.getBorrowStatus()),
                BorrowRecord::getBorrowStatus,
                borrowRecordQuery.getBorrowStatus());

        borrowRecordLambdaQuery.or();

        //借款名称查询  模糊查询
        borrowRecordLambdaQuery.like(
                !StringUtils.isEmpty(borrowRecordQuery.getName()),
                BorrowRecord::getName,
                borrowRecordQuery.getName()
        );

        IPage<BorrowRecord> p = page(page, borrowRecordLambdaQuery);

        //03 返回 分页查询需要的封装数据
        Pages<BorrowRecordVo> pages = new Pages<>();

        List<BorrowRecord> records = p.getRecords();
        //hutool bean的copy工具
        List<BorrowRecordVo> borrowRecordVos = BeanUtil.copyToList(records, BorrowRecordVo.class);

        pages.setList(borrowRecordVos);
        pages.setPageNum(p.getCurrent());
        pages.setPageSize(p.getPages());
        pages.setTotal(p.getTotal());

        return pages;
    }

    @Autowired
    private TradeLogApi tradeLogApi;

    /**
     * 借款审核 业务实现 
     * @param approveStatus
     * @param borrowRecordId
     * @return
     */
    @Override
    public String verifyStatus(Integer approveStatus, Long borrowRecordId) {
        //正常的需要token  校验接口
        //01 生成流水号 更新借款记录
        String reqCode = "REQ_"+ UUID.randomUUID().toString().substring(0,12);
        //查询 借款记录
        BorrowRecord borrowRecord = getById(borrowRecordId);
        //设置流水
        borrowRecord.setReqCode(reqCode);
        //更新
        updateById(borrowRecord);

        //02 调用托管服务   需要远程调用
        BorrowSyncRecordVo borrowSyncRecordVo = new BorrowSyncRecordVo();
        //发送远程数据
        borrowSyncRecordVo.setReqCode(borrowRecord.getReqCode());
        borrowSyncRecordVo.setAmount(borrowRecord.getAmount());
        borrowSyncRecordVo.setId(borrowRecord.getId());
        borrowSyncRecordVo.setName(borrowRecord.getName());
        borrowSyncRecordVo.setPeriod(borrowRecord.getPeriod());
        borrowSyncRecordVo.setUserCode(borrowRecord.getUserCode());
        borrowSyncRecordVo.setUserId(borrowRecord.getUserId());
        borrowSyncRecordVo.setBorrowRecordNo(borrowRecord.getBorrowRecordNo());

        System.out.println("远程调用 发送数据: borrowSyncRecordVo = " + borrowSyncRecordVo);
        //返回结果是 Result
        Result<BaseResult> resultResult = tradeLogApi.syncBorrowRecord(borrowSyncRecordVo);
        BaseResult baseResult = resultResult.getData();

        //03 拿到调用结果 (把borrowRecord status修改1 和  borrow_status 进行状态修改);
        log.info("远程调用银行返回的结果是:", baseResult);
        boolean flag = true; //模拟成功了
        if (StringUtils.hasText(baseResult.getRespMsg()) && baseResult.getRespMsg().equals("成功")){
            borrowRecord.setStatus(true);  // 可以状态
            borrowRecord.setBorrowStatus("SYNC"); // 数据同步状态
            updateById(borrowRecord);
        }
        return "借款审核结束....";
    }

    /**
     * 用户名
     * @param userInfoVo
     * @return
     */
    private String covertName(UserInfoVo userInfoVo) {

        //张先生 第几次借款
        StringBuilder sb = new StringBuilder();
        //姓 的截取
        String firstName = userInfoVo.getUserName().substring(0, 1);
        String identityCode = userInfoVo.getIdentityCode();
        //判断 identityCode 长度 如果不够 抛出异常
        String numCode = identityCode.substring(16,17);
        //性别  第17为 如果是偶数是女士  奇数是 先生
        String sex = Integer.parseInt(numCode) % 2 == 0 ? "女士":"先生";

        //借款次数
        Long count = count(Wrappers.lambdaQuery(BorrowRecord.class).
                eq(BorrowRecord::getUserCode,userInfoVo.getUserCode()));

        sb.append(firstName);
        sb.append(sex);
        sb.append(",第" + (count + 1) +"次借款");

        return sb.toString();
    }

    public static void main(String[] args) {

        String identityCode = "199111223366554495";
        String numCode = identityCode.substring(16,17);
        System.out.println("numCode = " + numCode);

    }
}
